<?php

namespace App\Service;

use App\Exceptions\ApiException;
use App\Models\Booking;
use Carbon\Carbon;

class BookingService
{
    /**
     * 获取拼本列表
     *
     * @param array $params 查询参数
     * @return array
     */
    public function list(array $params): array
    {
        $query = Booking::query();

        // 查询用户名称、预订时间、店铺名称、剧本名称、剧本详情字段
        $query->select('user_id', 'user_name', 'booking_time', 'store_name', 'script_name', 'script_details', 'discount_type', 'is_api', 'wechat_no');

        // 模糊搜索 user_name store_name script_name script_details
        if (!empty($params['search'])) {
            $search = $params['search'];
            $query->where(function ($q) use ($search) {
                $q->where('script_details', 'like', "%$search%");
                $q->orWhere("user_name", "like", "%$search%");
                $q->orWhere("store_name", "like", "%$search%");
                $q->orWhere("script_name", "like", "%$search%");
            });
        }

        // 根据时间查询，传来的参数为2025-07-18，查询2025-07-18 00:00:00 到 2025-07-18 23:59:59 之间的数据
        if (!empty($params['date'])) {
            $date      = $params['date'];
            $startTime = Carbon::parse($date)->startOfDay();
            $endTime   = Carbon::parse($date)->endOfDay();
            $query->whereBetween('booking_time', [$startTime, $endTime]);
        }

        // 用户id查询
        if (!empty($params['user_id'])) {
            $query->where('user_id', $params['user_id']);
        } else {
            // 开本时间大于等于当前时间
            $query->where('booking_time', '>=', Carbon::now());
        }

        // 低价
        if (!empty($params['is_low_price']) && $params['is_low_price'] == 1) {
            $query->whereIn('discount_type', ['低价', '免单']);
        }

        // 未过期 大于当前时间
        $query->where('expire_time', '>=', Carbon::now());

        // 分页
        $page     = max(1, intval($params['page'] ?? 1));
        $pageSize = max(1, intval($params['page_size'] ?? 10));

        $total = $query->count();
        $list  = $query->orderBy('is_api', 'desc')->orderBy('booking_time')->orderBy('create_time')
            ->forPage($page, $pageSize)
            ->get()
            ->toArray();
        return [
            'list'      => $list,
            'total'     => $total,
            'page'      => $page,
            'page_size' => $pageSize,
        ];
    }

    /**
     * 新增拼本
     *
     * @param array $params
     * @return array
     */
    public function create(array $params): array
    {
        // 只允许指定字段批量赋值
        $data = [
            'user_id'        => $params['user_id'] ?? '',
            'user_name'      => $params['user_name'] ?? '',
            'booking_time'   => $params['booking_time'] ?? '',
            'store_name'     => $params['store_name'] ?? '',
            'script_name'    => $params['script_name'] ?? '',
            'script_details' => $params['script_details'] ?? '',
            'expire_time'    => $params['booking_time'] ?? '',
            'is_api'         => $params['is_api'] ?? 0,
            'wechat_no'      => $params['wechat_no'] ?? '',
            'create_time'    => date('Y-m-d H:i:s'),
            'update_time'    => date('Y-m-d H:i:s'),
        ];
        // unique_no
        $data['unique_no'] = md5("{$data['booking_time']}_{$data['store_name']}_{$data['script_name']}_{$data['script_details']}");
        $booking           = Booking::query()->create($data);
        return $booking ? $booking->toArray() : [];
    }

    /**
     * 我发布的列表
     *
     * @param array $params
     * @return array
     */
    public function myList(array $params): array
    {
        $query = Booking::query();
        $query->where('user_id', $params['user_id']);
        $page     = max(1, intval($params['page'] ?? 1));
        $pageSize = max(1, intval($params['page_size'] ?? 10));
        $total    = $query->count();
        $list     = $query->orderByDesc('update_time')
            ->forPage($page, $pageSize)
            ->get()
            ->toArray();
        return [
            'list'      => $list,
            'total'     => $total,
            'page'      => $page,
            'page_size' => $pageSize,
        ];
    }

    /**
     * 检查拼本是否存在
     *
     * @param int $id
     * @param string $user_id
     * @return bool
     */
    public function checkExists(int $id, string $user_id): bool
    {
        return Booking::query()->where('id', $id)->where('user_id', $user_id)->exists();
    }

    /**
     * 修改拼本
     *
     * @param array $params
     * @return array
     * @throws ApiException
     */
    public function update(array $params): array
    {
        $booking = Booking::query()->where('id', $params['id'])->where('user_id', $params['user_id'])->first();
        if (!$booking) {
            throw new ApiException('拼布信息不存在');
        }
        $fields = ['user_name', 'booking_time', 'store_name', 'script_name', 'script_details'];
        foreach ($fields as $field) {
            if (isset($params[$field])) {
                $booking->$field = $params[$field];
                // 当 booking_time存在时，将过期时间更新为 开本时间
                if ($field == 'booking_time') {
                    $booking->expire_time = $params[$field];
                }
            }
        }
        $booking->unique_no   = md5("{$params['booking_time']}_{$params['store_name']}_{$params['script_name']}_{$params['script_details']}");
        $booking->update_time = date('Y-m-d H:i:s');
        $booking->save();
        return $booking->toArray();
    }
}
